what's wrong with Bamboo
if you used travis-ci on github, you may familiar with this thing when sending pull request
those green things came from github status api.
but bamboo does not come with native support for github status api
but here's some hack you can do to achieve similar thing travis does.
bamboo magic
there's thing in bamboo called custom build
, which mean you can custom variable in bamboo's build.
you can simply trigger a custom build via GUI
or API
curl -XPOST -u name:password http://your.bamboo.domain/rest/api/latest/queue/:build-key?bamboo.variable.blah=blahblah
then the custom varibale is available via $bamboo_blah
and your build will also display a little bit different such as
github webhook
now we can config github webhook say, ok, I'd like bamboo to be trigger whenever a pull request is opened.
with the hubot endpoint and variable we need
but what about the custom variables
bamboo need special form of variables, so we need something middleware to convert webhook payload from github…
I simply create a hubot and a very simple script checkout completed source code here https://gist.github.com/jcouyang/0201a80d4657b000cec7 to achieve that.
robot.router.post "/hubot/trigger-bamboo", (req, res) ->
query = querystring.parse(url.parse(req.url).query)
bamboo_url = query.bamboo
build_key = query.buildKey
room = query.room
res.end "" if !bamboo_url || !room
data = req.body
eventType = req.headers["x-github-event"]
console.log "Processing event type #{eventType}..."
try
if eventType in eventTypes
robot.http("#{bamboo_url}/rest/api/latest/queue/#{build_key}?bamboo.variable.pull_sha=#{data.pull_request.head.sha}&bamboo.variable.pull_num=#{data.number}") (post-bamboo-api)
.post()
you can easily install the script for you hubot
npm install hubot-bamboo-pr --save
andd add it to external-scripts.json
file
[
"hubot-something-else",
+ "hubot-bamboo-pr"
]
then point your github hook to hubot.
config Bamboo plan
We'd like only run the PR only in testing, and stop build after testing. imaging if your build originally looks like this:
- testing
- checkout code
- run test
- tagging
- publish
- deploy to Staging
- deploy to Production
so here're things a PR build should look like:
- testing
- checkout code
- checkout pull request code
- run test
- notify github status api
- stop build when it's a PR build
- tagging
- publish
- deploy to Staging
- deploy to Production
so when build trigger by hubot with custom variables, ideally your build should look like:
some credentials you may need
$bamboo_GITHUB_STATUS_API_password
you need github status api token here there and everywhere
you can get a status api token from github GUI Setting > Applications > Generate new token
tick only repo:status
for Status API purpose only and much more safer.
$bamboo_BAMBOO_password
you need bamboo password for stoping build, just create a share user with less permission
checkout PR code
#!/bin/bash
GITHUB_API=https://api.github.com
# if github enterprise https://your.github.domain/api/v3
if [[ -n ${bamboo_pull_num} ]]; then
echo "== send pending status =="
curl -H "Authorization: token $bamboo_GITHUB_STATUS_API_password" --request POST -k --data "{\"state\": \"pending\", \"description\": \"building...\", \"target_url\": \"$bamboo_resultsUrl\"}" https://$GITHUB_API/repos/the-money/condor/statuses/$bamboo_pull_sha > /dev/null
echo "git fetch PR $bamboo_pull_num =="
git fetch ${bamboo.repository.git.repositoryUrl} +refs/pull/$bamboo_pull_num/merge:
git checkout FETCH_HEAD
fi
notify github status
1: #!/bin/bash
2: STATUS=$?
3: if [[ -n ${bamboo_pull_sha} ]]; then
4: if [ $STATUS != 0 ]; then
5: echo 'pull reqeust build failed'
6: curl -k -H "Authorization: token $bamboo_GITHUB_STATUS_API_password" --request POST --data "{\"state\": \"failure\", \"description\": \"failure:(\", \"target_url\": \"${bamboo.buildResultsUrl}\"}" $GITHUB_API/repos/:user/:repo/statuses/$bamboo_pull_sha > /dev/null
7: else
8: echo 'pull request build success'
9: curl -k -H "Authorization: token $bamboo_GITHUB_STATUS_API_password" --request POST --data "{\"state\": \"success\", \"description\": \"Success:)\", \"target_url\": \"${bamboo.buildResultsUrl}\"}" $GITHUB_API/repos/:user/:repo/statuses/$bamboo_pull_sha > /dev/null
10: fi
11: fi
place checkout PR
and notify github status
script in this order
stop build if PR
create new stage for stop build task
1: #!/bin/bash
2: if [[ -n ${bamboo_pull_num} ]]; then
3: echo 'stoping bamboo'
4: curl "http://${bamboo_BAMBOO_USER}:${bamboo_BAMBOO_password}@your.bamboo.domain/build/admin/stopPlan.action?${bamboo.planResultKey}-${bamboo.buildNumber}"
5: fi
Footnotes:
checkout completed source code here https://gist.github.com/jcouyang/0201a80d4657b000cec7